/* 
 *  Ajax类
 *  开发：Amron
 *  日期：6-22
 */

import { AJAX_OPTIONS_DEFAULT } from "./default";
import { objToForm, spliceURL } from "./utils";
import { CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_JSON, HTTP_GET_REQUEST } from "./constants";

class Ajax {

    constructor(url, options) {

        this.url = url;

        this.xhr = new XMLHttpRequest();

        this.options = Object.assign({}, AJAX_OPTIONS_DEFAULT, options);

        this.init();
    }

    // 初始化各种参数
    init() {

        // 绑定各个事件
        this.bindEvents();

        // 准备发送请求
        this.xhr.open(this.options.method, spliceURL(this.url, this.options.params), true);

        // 设置响应数据类型
        this.setResponseType();

        // 设置是否传cookie
        this.setCookie();

        // 设置超时时间
        this.setTimeout();

        // 设置请求头字段
        this.setContentType();

        // 发送请求
        this.send();

    }

    bindEvents() {

        const xhr = this.xhr;
        const { success, responseError, requestError, abort, timeout } = this.options;

        // success and responseError
        xhr.addEventListener('load', () => {

            if (this.statusIsOk()) {

                success(xhr.response, xhr);
            } else {

                responseError(xhr.status, xhr)
            }

        })

        // requestError
        xhr.addEventListener('error', () => {
            requestError(xhr);
        })

        // abort
        xhr.addEventListener('abort', () => {
            abort(xhr);
        })

        // success（）
        xhr.addEventListener('timeout', () => {
            timeout(xhr);
        })

    }

    // 设置响应数据类型
    setResponseType() {
        if (this.options.responseType)
            this.xhr.responseType = this.options.responseType;
    }

    // 设置请求头字段
    setContentType() {
        if (this.options.contentType)
            this.xhr.setRequestHeader('Content-Type', this.options.contentType);
    }

    // 设置是否传cookie
    setCookie() {
        if (this.options.withCredential)
            this.xhr.withCredentials = true;
    }

    // 设置超时时间
    setTimeout() {
        if (this.options.timeoutTime > 0)
            this.xhr.timeout = this.options.timeoutTime;
    }

    // 发送请求
    send() {

        const { method, contentType, data } = this.options, xhr = this.xhr;

        let result = data;

        // 没有data或者get请求的情况
        if (method.toUpperCase() === HTTP_GET_REQUEST || data === null) return xhr.send(null);

        // 发送form表单形式的数据格式
        if (contentType.toLowerCase().includes(CONTENT_TYPE_FORM_URLENCODED)) {

            result = objToForm(result);
        }

        // 发送JSON格式的数据
        if (contentType.toLowerCase().includes(CONTENT_TYPE_JSON)) {

            result = JSON.stringify(result);
        }

        xhr.send(result);
    }

    // 判断响应是否出错
    statusIsOk() {
        return this.xhr.status >= 200 && this.xhr.status < 300 || this.xhr.status === 304
    }

}

export default Ajax;


